/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.buss.core.utils;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;

/**
 * 图片操作类
 * 
 * @author Administrator
 */
public class ImageUtil {

    /**
     * 按比例缩放图片
     *
     * @param srcImage
     * @param rate
     * @return
     */
    public static BufferedImage scaleRate(BufferedImage srcImage, double rate) {
        return scaleRate(srcImage, rate, rate, null);
    }

    /**
     * 按比例缩放图片
     *
     * @param srcImage
     * @param width
     * @param height
     * @return
     */
    public static BufferedImage scaleRate(BufferedImage srcImage, int width,
            int height) {
        double w = srcImage.getWidth();
        double h = srcImage.getHeight();
        if ((w < width) && (h < height)) {
            return srcImage;
        }
        if (height == 0) {
            if (w <= width) {
                return srcImage;
            }
            return scaleRate(srcImage, width / w, width / w, null);
        }
        if (width == 0) {
            if (h <= height) {
                return srcImage;
            }
            return scaleRate(srcImage, height / h, height / h, null);
        }
        if (w / h > width / height) {
            return scaleRate(srcImage, width / w, width / w, null);
        }
        return scaleRate(srcImage, height / h, height / h, null);
    }

    /**
     * 按比例缩放图片
     *
     * @param srcImage
     * @param xscale
     * @param yscale
     * @param hints
     * @return
     */
    public static BufferedImage scaleRate(BufferedImage srcImage,
            double xscale, double yscale, RenderingHints hints) {
        int width = (int) (srcImage.getWidth() * xscale);
        int height = (int) (srcImage.getHeight() * yscale);
        BufferedImage image = new BufferedImage(width, height, 1);
        image.getGraphics().drawImage(
                srcImage.getScaledInstance(width, height, 16), 0, 0, null);
        return image;
    }

    /**
     * 按指定宽高缩放图片
     *
     * @param srcImage
     * @param width
     * @param height
     * @param changeRate
     * @return
     */
    public static BufferedImage scaleFixed(BufferedImage srcImage, int width,
            int height, boolean changeRate) {
        if (changeRate) {
            int srcWidth = srcImage.getWidth();
            int srcHeight = srcImage.getHeight();
            int w = 0;
            int h = 0;
            double wScale = srcWidth * 1.0D / width * 1.0D;
            double hScale = srcHeight * 1.0D / height * 1.0D;
            if (wScale > hScale) {
                int srcWidth2 = (int) (width * hScale);
                w = (srcWidth - srcWidth2) / 2;
                srcWidth = srcWidth2;
                h = 0;
            } else {
                int srcHeight2 = (int) (height * wScale);
                h = (srcHeight - srcHeight2) / 2;
                srcHeight = srcHeight2;
                w = 0;
            }
            ImageFilter cropFilter = new CropImageFilter(h, h, srcWidth,
                    srcHeight);
            Image img = Toolkit.getDefaultToolkit().createImage(
                    new FilteredImageSource(srcImage.getSource(), cropFilter));
            BufferedImage bi = new BufferedImage(srcWidth, srcHeight, 1);
            bi.getGraphics().drawImage(img, 0, 0, null);
            return scaleRate(bi, width, height);
        }
        BufferedImage bi = new BufferedImage(width, height, 1);
        bi.getGraphics().drawImage(
                srcImage.getScaledInstance(width, height, 16), 0, 0, null);
        return bi;
    }

    /**
     * 按指定宽高缩放图片文件
     *
     * @param srcFile
     * @param destFile
     * @param width
     * @param height
     * @return
     */
    public static void scaleFixedImageFile(String srcFile, String destFile,
            int width, int height) throws IOException {
        scaleFixedImageFile(srcFile, destFile, width, height, true);
    }

    /**
     * 按指定宽高缩放图片文件
     * @param file
     * @param distFile
     * @param width
     * @param height
     * @param changeRate
     * @throws IOException
     */
    public static void scaleFixedImageFile(File file, String distFile, int width, int height, boolean changeRate)
            throws IOException {
        try {
            BufferedImage image = ImageIO.read(file);
            BufferedImage newImage = scaleFixed(image, width, height, changeRate);
            writeImageFile(distFile, newImage);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 按指定宽高缩放图片文件
     *
     * @param srcFile
     * @param destFile
     * @param width
     * @param height
     * @param changeRate
     * @return
     */
    public static void scaleFixedImageFile(String srcFile, String destFile,
            int width, int height, boolean changeRate) throws IOException {
        File f = new File(srcFile);
        try {
            BufferedImage image = ImageIO.read(f);
            BufferedImage newImage = scaleFixed(image, width, height,
                    changeRate);
            writeImageFile(destFile, newImage);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 按比例缩放图片文件
     *
     * @param srcFile
     * @param destFile
     * @param width
     * @param height
     * @return
     */
    public static void scaleRateImageFile(String srcFile, String destFile,
            int width, int height) throws IOException {
        File f = new File(srcFile);
        try {
            BufferedImage image = ImageIO.read(f);
            BufferedImage newImage = scaleRate(image, width, height);
            writeImageFile(destFile, newImage);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 按指定宽高缩放图片文件
     * @param file
     * @param distFile
     * @param width
     * @param height
     * @param changeRate
     * @throws IOException
     */
    public static void scaleRateImageFile(File file, String distFile, int width, int height)
            throws IOException {
        try {
            BufferedImage image = ImageIO.read(file);
            BufferedImage newImage = scaleRate(image, width, height);
            writeImageFile(distFile, newImage);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 按比例缩放图片文件
     *
     * @param srcFile
     * @param destFile
     * @param rate
     * @return
     */
    public static void scaleRateImageFile(String srcFile, String destFile,
            double rate) throws IOException {
        File f = new File(srcFile);
        try {
            BufferedImage image = ImageIO.read(f);
            BufferedImage newImage = scaleRate(image, rate);
            writeImageFile(destFile, newImage);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取灰度图
     *
     * @param srcImage
     * @return
     */
    public static BufferedImage gray(BufferedImage srcImage) {
        BufferedImage dstImage = new BufferedImage(srcImage.getWidth(),
                srcImage.getHeight(), srcImage.getType());
        Graphics2D g2 = dstImage.createGraphics();
        RenderingHints hints = g2.getRenderingHints();
        g2.dispose();
        ColorSpace grayCS = ColorSpace.getInstance(ColorSpace.CS_GRAY);
        ColorConvertOp colorConvertOp = new ColorConvertOp(grayCS, hints);
        colorConvertOp.filter(srcImage, dstImage);
        return dstImage;
    }

    /**
     * 获取灰度图文件
     *
     * @param srcFile
     * @param destFile
     * @return
     */
    public static void grayImageFile(String srcFile, String destFile)
            throws IOException {
        writeImageFile(destFile, gray(ImageIO.read(new File(srcFile))));
    }

    /**
     * 写图片文件
     *
     * @param fileName
     * @param image
     * @return
     */
    public static void writeImageFile(String fileName, BufferedImage image)
            throws IOException {
        FileOutputStream fos = new FileOutputStream(fileName);
        if (fileName.toLowerCase().endsWith(".gif")) {
            GIFEncoder gif = new GIFEncoder(image, fos);
            gif.encode();
            //Jimi.createJimiWriter(arg0, arg1)
        } else {
            //if ((fileName.toLowerCase().endsWith(".jpg"))
            //		|| (fileName.toLowerCase().endsWith(".jpeg"))) {
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(fos);
            JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(image);

            param.setQuality(1.0F, false);
            encoder.encode(image);
            //}
        }
        fos.flush();
        fos.close();
    }

    /**
     * 获取图片尺寸（高、宽）
     *
     * @param fileName
     * @return
     */
    public static Dimension getDimension(String fileName) throws IOException {
        File f = new File(fileName);
        return getDimension(f);
    }

    /**
     * 获取图片尺寸（高、宽）
     *
     * @param f
     * @return
     */
    public static Dimension getDimension(File f) throws IOException {
        BufferedImage image = ImageIO.read(f);
        if (image == null) {
            return new Dimension(0, 0);
        }
        return new Dimension(image.getWidth(), image.getHeight());
    }

    /**
     * 图片水印
     * @param file<需要打水印的图片文件>
     * @param pressImg<水印图片路径>
     * @param position<水印位置,1:左上,2:上中,3:上右,4:左中,5:中,6:右中,7:左下,8:下中,9:右下>
     */
    public static final void pressImage(File file, String pressImg, int position) {
        try {
            Image src = ImageIO.read(file);
            int width = src.getWidth(null);
            int height = src.getHeight(null);
            if ((width <= 300) && (height <= 300)) {
                return;
            }
            BufferedImage image = new BufferedImage(width, height, 1);
            Graphics g = image.createGraphics();
            g.drawImage(src, 0, 0, width, height, null);
            File file_press = new File(pressImg);
            if (!(file_press.exists())) {
//                com.wepo.utils.Logger.warn("水印图片不存在:" + pressImg,
//                        ImageUtil.class);
                return;
            }
            Image src_press = ImageIO.read(file_press);
            int width_press = src_press.getWidth(null);
            int height_press = src_press.getHeight(null);
            int x = 0;
            int y = 0;
            int bianju = 20;
            int[][][] positions = {
                {{bianju, bianju},
                    {(width - width_press) / 2, bianju},
                    {width - width_press - bianju, bianju}},
                {
                    {bianju, (height - height_press) / 2},
                    {(width - width_press) / 2,
                        (height - height_press) / 2},
                    {width - width_press - bianju,
                        (height - height_press) / 2}},
                {
                    {bianju, height - height_press - bianju},
                    {(width - width_press) / 2,
                        height - height_press - bianju},
                    {width - width_press - bianju,
                        height - height_press - bianju}}};
            if (position == 0) {
                position = NumberUtil.getRandomInt(9) + 1;
            }
            x = positions[((position - 1) / 3)][((position - 1) % 3)][0];
            y = positions[((position - 1) / 3)][((position - 1) % 3)][1];
            g.drawImage(src_press, x, y, width_press, height_press, null);
            g.dispose();
            FileOutputStream out = new FileOutputStream(file);
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            encoder.encode(image);
            out.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 图片水印	 *
     * @param targetImg<需要打水印的图片文件路径>
     * @param pressImg<水印图片路径>
     * @param position<水印位置,1:左上,2:上中,3:上右,4:左中,5:中,6:右中,7:左下,8:下中,9:右下>
     * @return
     */
    public static final void pressImage(String targetImg, String pressImg,
            int position) {
        File file = new File(targetImg);
        pressImage(file, pressImg, position);
    }

    /**
     * 图片水印
     * 默认水印位置为右下
     * @param targetImg<需要打水印的图片文件路径>
     * @param pressImg<水印图片路径>
     * @return
     */
    public static final void pressImage(String targetImg, String pressImg) {
        pressImage(targetImg, pressImg, 9);
    }

    /**
     * 图片水印
     * 默认水印位置为右下
     * @param file<需要打水印的图片文件>
     * @param pressImg<水印图片路径>
     */
    public static final void pressImage(File file, String pressImg) {
        pressImage(file, pressImg, 9);
    }

    /**
     * 文字水印
     * @param file<需要水印的图片文件>
     * @param pressText<水印文字>
     * @param fontName<文字字体>
     * @param fontStyle<文字风格，如:斜体，加粗等>
     * @param color	<文字颜色>
     * @param fontSize	<文字大小>
     * @param position	<水印位置,1:左上,2:上中,3:上右,4:左中,5:中,6:右中,7:左下,8:下中,9:右下>
     */
    public static void pressText(File file, String pressText, String fontName,
            int fontStyle, int color, int fontSize, int position) {
        try {
            Image src = ImageIO.read(file);
            int width = src.getWidth(null);
            int height = src.getHeight(null);
            if ((width <= 300) && (height <= 300)) {
                return;
            }
            BufferedImage image = new BufferedImage(width, height, 1);
            Graphics g = image.createGraphics();
            g.drawImage(src, 0, 0, null);
            g.setColor(new Color(color));
            g.setFont(new Font(fontName, fontStyle, fontSize));
            int x;
            int y;
            int bianju = 60;
            int[][][] positions = {
                {
                    {bianju, bianju},
                    {(width - (pressText.length() * fontSize)) / 2,
                        bianju},
                    {width - (pressText.length() * fontSize) - bianju,
                        bianju}},
                {
                    {bianju, (height - fontSize) / 2},
                    {(width - (pressText.length() * fontSize)) / 2,
                        (height - fontSize) / 2},
                    {width - (pressText.length() * fontSize) - bianju,
                        (height - fontSize) / 2}},
                {
                    {bianju, height - fontSize - bianju},
                    {(width - (pressText.length() * fontSize)) / 2,
                        height - fontSize - bianju},
                    {width - (pressText.length() * fontSize) - bianju,
                        height - fontSize - bianju}}};
            if (position == 0) {
                position = NumberUtil.getRandomInt(9) + 1;
            }
            x = positions[((position - 1) / 3)][((position - 1) % 3)][0];
            y = positions[((position - 1) / 3)][((position - 1) % 3)][1];
            g.drawString(pressText, x, y);
            g.dispose();
            FileOutputStream out = new FileOutputStream(file);
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            encoder.encode(image);
            out.close();
        } catch (Exception e) {
            System.out.println(e);

        }
    }

    /**
     * 压缩图片文件
     *
     * @param targetImg<需要水印的图片文件路径>
     * @param pressText<水印文字>
     * @param fontName<文字字体>
     * @param fontStyle<文字风格，如:斜体，加粗等>
     * @param color<文字颜色>
     * @param fontSize<文字大小>
     * @param position<水印位置,1:左上,2:上中,3:上右,4:左中,5:中,6:右中,7:左下,8:下中,9:右下>
     * @return
     */
    public static void pressText(String targetImg, String pressText,
            String fontName, int fontStyle, int color, int fontSize,
            int position) {
        try {
            File file = new File(targetImg);
            pressText(file, pressText, fontName, fontStyle, color, fontSize, position);
        } catch (Exception e) {
            System.out.println(e);
        }
    }

    public static void main(String[] args) {
        try {
            scaleFixedImageFile("e:/1.gif", "e:/3.gif", 50, 50);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
